package com.hexacta.hrs.web.struts.actions.exchange;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;

import com.hexacta.hrs.domain.exchange.Currency;
import com.hexacta.hrs.domain.exchange.Exchange;
import com.hexacta.hrs.domain.exchange.ExchangeItem;
import com.hexacta.hrs.services.crud.CrudService;
import com.hexacta.hrs.services.exchange.ExchangeService;
import com.hexacta.hrs.web.struts.actions.CrudAbstractAction;

public class ExchangeAction extends CrudAbstractAction<Exchange> {

    /**
     * 
     */
    private static final long serialVersionUID = -637736393164256373L;

    private ExchangeService exchangeService;

    /* Defines */

    /* Parameters */

    private Currency selectedCurrency;

    private Long selectedExchangeItemId;

    private Date formDateFrom;

    private String formARSValue;

    /* Variables */

    private Exchange filteredExchange;

    private Long exchangeId;

    /* Actions */

    public String filter() {

        if (selectedCurrency != null) {
            Exchange matching = new Exchange();
            matching.setCurrency(selectedCurrency);
            List<Exchange> exchanges = (List<Exchange>) exchangeService.searchByCriteria(matching);
            if (exchanges.isEmpty()) {
                filteredExchange = matching;
            } else {
                filteredExchange = exchanges.get(0);
                exchangeId = filteredExchange.getId();
            }
        }
        return SUCCESS;
    }

    public String deleteItem() {

        Exchange exchange = exchangeService.searchById(exchangeId);
        exchange.removeItem(selectedExchangeItemId);

        selectedCurrency = exchange.getCurrency();

        return filter();
    }

    public String createItem() {

        Exchange exchange = null;

        if (exchangeId != null) {
            exchange = exchangeService.searchById(exchangeId);
        }

        if (exchange == null) {
            exchange = new Exchange();
            exchange.setCurrency(selectedCurrency);
        }

        ExchangeItem newItem = new ExchangeItem();

        newItem.setDateFrom(formDateFrom);
        newItem.setValueARS(Double.parseDouble(formARSValue));

        exchange.getExchanges().add(newItem);
        exchangeService.save(exchange);

        return filter();
    }

    public String editItem() {
        Exchange exchange = null;

        if (exchangeId == null)
            throw new IllegalArgumentException();

        exchange = exchangeService.searchById(exchangeId);

        if (exchange == null)
            throw new IllegalStateException();

        ExchangeItem item = exchange.findItem(selectedExchangeItemId);

        item.setDateFrom(formDateFrom);

        try {
            item.setValueARS(Double.parseDouble(formARSValue));
        } catch (NumberFormatException e) {
            addActionError("The value in ARS must be a double with '.' as decimal separator.");
            return ERROR;
        }

        exchangeService.save(exchange);

        return filter();
    }

    /* Getters and Setters */

    /**
     * @return the exchangeService
     */
    public ExchangeService getExchangeService() {
        return exchangeService;
    }

    /**
     * @param exchangeService
     *            the exchangeService to set
     */
    public void setExchangeService(final ExchangeService exchangeService) {
        this.exchangeService = exchangeService;
    }

    /**
     * @return the selectedCurrency
     */
    public Currency getSelectedCurrency() {
        return selectedCurrency;
    }

    /**
     * @param selectedCurrency
     *            the selectedCurrency to set
     */
    public void setSelectedCurrency(final Currency selectedCurrency) {
        this.selectedCurrency = selectedCurrency;
    }

    /**
     * @return the selectedExchangeItemId
     */
    public Long getSelectedExchangeItemId() {
        return selectedExchangeItemId;
    }

    /**
     * @param selectedExchangeItemId
     *            the selectedExchangeItemId to set
     */
    public void setSelectedExchangeItemId(final Long selectedExchangeItemId) {
        this.selectedExchangeItemId = selectedExchangeItemId;
    }

    /**
     * @return the formDateFrom
     */
    public Date getFormDateFrom() {
        return formDateFrom;
    }

    /**
     * @param formDateFrom
     *            the formDateFrom to set
     */
    public void setFormDateFrom(final Date formDateFrom) {
        this.formDateFrom = formDateFrom;
    }

    /**
     * @return the formARSValue
     */
    public String getFormARSValue() {
        return formARSValue;
    }

    /**
     * @param formARSValue
     *            the formARSValue to set
     */
    public void setFormARSValue(final String formARSValue) {
        this.formARSValue = formARSValue;
    }

    /**
     * @return the serialversionuid
     */
    public static long getSerialversionuid() {
        return serialVersionUID;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected CrudService<Exchange> getCrudService() {
        return exchangeService;
    }

    public List<Currency> getCurrencies() {

        Currency[] currencies = Currency.values();

        ArrayList<Currency> ret = new ArrayList<Currency>();
        CollectionUtils.addAll(ret, currencies);

        return ret;
    }

    /**
     * @return the filteredExchange
     */
    public Exchange getFilteredExchange() {
        return filteredExchange;
    }

    public List<ExchangeItem> getExchangeItems() {
        List<ExchangeItem> ret = new ArrayList<ExchangeItem>();
        if (filteredExchange != null) {
            ret.addAll(filteredExchange.getExchanges());
        }
        return ret;
    }

    /**
     * @return the exchangeId
     */
    public Long getExchangeId() {
        return exchangeId;
    }

    /**
     * @param exchangeId
     *            the exchangeId to set
     */
    public void setExchangeId(final Long exchangeId) {
        this.exchangeId = exchangeId;
    }
}